package handler

import (
    "fcs-api/src/app/business"
    "fcs-api/src/app/model"
    "fcs-api/src/app/service/invoke"
    "fcs-api/src/client/tms"
    "fmt"
    "net/http"

    i18n "git.inspur.com/x/common/i18n"
    "github.com/emicklei/go-restful"
)

func (api *APIHandler) handleCreateFunction(request *restful.Request, response *restful.Response) {
    logger.Debug("handleCreateFunction start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleCreateFunction get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }

    functionInfo, err := validateAddFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    token := request.HeaderParameter("Authorization")
    projectId := request.HeaderParameter("x-project")
    functionInfo, err = business.CreateFunction(fcClient, functionInfo, token, projectId)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }
    logger.Debug("handleCreateFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfo)
}

func (api *APIHandler) handleCopyFunction(request *restful.Request, response *restful.Response) {
    logger.Debug("handleCreateFunction start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleCreateFunction get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }

    functionInfo, functionCopyInfo, err := validateCopyFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    // 复制函数代码
    err = functionOssCopy(functionInfo.A5tId, functionCopyInfo.SourceGroupName, functionCopyInfo.SourceFunctionName,
        functionCopyInfo.TragetGroupName, functionCopyInfo.NewFunctionName)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    token := request.HeaderParameter("Authorization")
    projectId := request.HeaderParameter("x-project")
    // 创建新函数
    functionInfo, err = business.CreateFunction(fcClient, functionInfo, token, projectId)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }
    logger.Debug("handleCreateFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfo)
}

func (api *APIHandler) handleUpdateFunction(request *restful.Request, response *restful.Response) {
    logger.Debug("handleUpdateFunction start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleUpdateFunction: get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, i18n.GetMessage(request.Request, "fcs.function.update")))
        return
    }

    updateModel, err := validateUpdateFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    extType := request.HeaderParameter("extType")
    if updateModel.FuncInfo.GroupName == model.ExtIds && extType != model.ExtIds {
        handleInternalError(response, model.InternalServerError(model.FunctionDeleteError, "数据铁笼函数禁止修改"))
        return
    }
    token := request.HeaderParameter("Authorization")
    functionInfo, err := business.UpdateFunction(fcClient, updateModel, token)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, i18n.GetMessage(request.Request, "fcs.function.update")))
        return
    }

    logger.Debug("handleUpdateFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfo)
}

func (api *APIHandler) handleUpdateFunctionLayer(request *restful.Request, response *restful.Response) {
    logger.Debug("handleUpdateFunctionLayer start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleUpdateFunctionLayer: get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, "更新函数失败"))
        return
    }

    updateModel, err := validateUpdateFunctionLayer(request)
    if err != nil {
        if model.IsNoNeedUpdate(err) {
            _ = response.WriteHeaderAndEntity(http.StatusOK, updateModel.FuncInfo)
            return
        }
        handleInternalError(response, err)
        return
    }
    functionInfo, err := business.UpdateFunction(fcClient, updateModel, "")
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, "更新函数失败"))
        return
    }

    logger.Debug("handleUpdateFunctionLayer end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfo)
}

func (api *APIHandler) handleGetFunctionDetail(request *restful.Request, response *restful.Response) {
    logger.Debug("handleUpdateFunction start.")
    functionInfo, err := validateGetFunctionDetail(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    logger.Debug("handleUpdateFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfo)
}

func (api *APIHandler) handleGetFunctionExist(request *restful.Request, response *restful.Response) {
    logger.Debug("handleGetFunctionExist start.")
    bool, err := validateIsFunctionExist(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    logger.Debug("handleGetFunctionExist end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, map[string]interface{}{"exist": bool})
}

func (api *APIHandler) handleGetFunctionList(request *restful.Request, response *restful.Response) {
    logger.Debug("handleGetFunctionList start.")
    from := request.QueryParameter("from")
    funcInfoQuery, err := validateGetFunctionList(request)
    if err != nil {
        if from == "apig" {
            _ = response.WriteHeaderAndEntity(http.StatusOK, &model.FunctionListResult{Result: []*model.FuncInfo{}})
            return
        }
        handleInternalError(response, err)
        return
    }
    funcInfoList, err := business.GetFunctionList(funcInfoQuery)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionGetError, i18n.GetMessage(request.Request, "fcs.function.list")))
        return
    }
    logger.Debug("handleGetFunctionList end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, funcInfoList)
}

func (api *APIHandler) handleDeleteFunction(request *restful.Request, response *restful.Response) {
    logger.Debug("handleCreateFunction start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleDeleteFunction: get cmanagerconfig error %v", err)
        handleInternalError(response, err)
        return
    }

    functionInfo, err := validateDeleteFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }

    extType := request.HeaderParameter("extType")
    if functionInfo.GroupName == model.ExtIds && extType != model.ExtIds {
        handleInternalError(response, model.InternalServerError(model.FunctionDeleteError, "数据铁笼函数禁止删除"))
        return
    }

    token := request.HeaderParameter("Authorization")
    err = business.DeleteFunction(fcClient, functionInfo, token)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionDeleteError, i18n.GetMessage(request.Request, "fcs.function.delete")))
        return
    }
    deleteCode(functionInfo.A5tId, functionInfo.GroupName, functionInfo.FunctionName)
    logger.Debug("handleCreateFunction end.")

    //标签管理同步删除
    err = tms.SendDeleteTagEvent(functionInfo.A5tId, tms.NewTag(functionInfo.Id, ""))
    if err != nil {
        logger.Error("delete fcs tms  error:", err)
    }
    response.WriteHeader(http.StatusOK)
}

func (api *APIHandler) handleInvokeFunction(request *restful.Request, response *restful.Response) {
    logger.Debug("handleInvokeFunction start.")

    user := currentUser(request)
    invokeInfo, err := validateInvokeFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    invokeInfo.Id = user.AccountId
    invokeInfo.Host = model.Base.FunctionInvokeHost

    invokeResult, err := invoke.CallFunction(invokeInfo)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionInvokeError, i18n.GetMessage(request.Request, "fcs.function.invoke")))
        return
    }
    logger.Debug("handleInvokeFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, invokeResult)
}

func (api *APIHandler) handleIsSubnetUsed(request *restful.Request, response *restful.Response) {
    isUsed, err := validateIsSubnetUsed(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }
    _ = response.WriteHeaderAndEntity(http.StatusOK, map[string]interface{}{
        "isUsed": isUsed,
    })
}
func (api *APIHandler) handleCreateFunctionExt(request *restful.Request, response *restful.Response) {
    logger.Debug("handleCreateFunctionExt start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleCreateFunction get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }

    functionInfo, err := validateAddFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }

    if functionInfo.GroupId == model.ExtIds {
        checkGroupId(api, request, response, functionInfo)
    }

    functionInfoExt, err := uploadCode(functionInfo, request, response)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }

    token := request.HeaderParameter("Authorization")
    projectId := request.HeaderParameter("X-Project")
    functionInfo, err = business.CreateFunction(fcClient, functionInfo, token, projectId)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionCreateError, i18n.GetMessage(request.Request, "fcs.function.create")))
        return
    }

    logger.Debug("handleCreateFunctionExt end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfoExt)
}

func (api *APIHandler) handleUpdateFunctionExt(request *restful.Request, response *restful.Response) {
    logger.Debug("handleUpdateFunction start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleUpdateFunction: get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, i18n.GetMessage(request.Request, "fcs.function.update")))
        return
    }

    updateModel, err := validateUpdateFunction(request)
    if err != nil {
        handleInternalError(response, err)
        return
    }

    token := request.HeaderParameter("Authorization")
    functionInfo, err := business.UpdateFunction(fcClient, updateModel, token)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, i18n.GetMessage(request.Request, "fcs.function.update")))
        return
    }

    if functionInfo.GroupId == model.ExtIds {
        checkGroupId(api, request, response, functionInfo)
    }

    functionInfoExt, err := uploadCode(functionInfo, request, response)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.FunctionUpdateError, i18n.GetMessage(request.Request, "fcs.function.update")))
        return
    }

    logger.Debug("handleUpdateFunction end.")
    _ = response.WriteHeaderAndEntity(http.StatusOK, functionInfoExt)
}

func (api *APIHandler) handleGetUrl(request *restful.Request, response *restful.Response) {
    logger.Debug("handleGetUrl start.")
    ui := &model.UrlInfo{}
    err := ReadAndValidateEntity(request, ui)
    if err != nil {
        _ = logger.Error("handleGetUrl ReadAndValidateEntity error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionUrlError, i18n.GetMessage(request.Request, "fcs.function.url")))
        return
    }
    f, err := model.GetFuncInfoById(ui.FuncId)
    if err != nil {
        _ = logger.Error("handleGetUrl GetFuncInfoById error %v", err)
        handleInternalError(response, model.InternalServerError(model.FunctionUrlError, i18n.GetMessage(request.Request, "fcs.function.url")))
        return
    }
    path := fmt.Sprintf("/sync/%s/%s/%s.%s", f.A5tId, ui.GroupName, ui.FuncName, ui.TargetName)
    _ = response.WriteHeaderAndEntity(http.StatusOK, map[string]string{"addr": model.Base.FunctionInvokeHost, "path": path})
}
